import interface
import oprt2sql
import oprt2wav
import wave
import numpy as np
import mythread
import pyqtgraph as pg
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from PyQt5.QtWidgets import QTableWidgetItem, QHeaderView, QMessageBox, QAbstractItemView, QPushButton, QWidget, QComboBox, QFrame,\
    QLineEdit, QTableWidget, QTabWidget, QVBoxLayout
from PyQt5.QtCore import Qt, QRect


class Operate2Inter(interface.Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.get_infos = 0
        self.infos = []
        self.titles = []
        self.curor = 0

        self.data = []
        self.params = []
        self.framerate = 0

        self.waveform = {}
        self.spectrogram = {}
        self.phonogram = {}

        self.qmessageBox = QMessageBox()
        self.sqloprter = oprt2sql.Operate2Sql("localhost", "root", "123456", "wavdata")
        self.wavoprter = oprt2wav.ProcessAudio()

    def setupUi(self, MainWindow):
        super().setupUi(MainWindow)
        self.MainWindow = MainWindow
        # 数据加载
        self.setsqloprter()
        self.getinfos()
        self.getdata()
        self.initplot_waveform()
        self.initplot_spectrogram()
        self.initplot_phonogram()
        # 初始设置
        self.settableWidget()
        self.setstylesheet()
        self.setMainWindow()
        self.init_tips()
        # 设置信号和槽----数据库处理
        self.pushButton.clicked.connect(self.next)
        self.pushButton_2.clicked.connect(self.last)
        # 设置信号和槽----音乐播放、停止
        self.pushButton_5.clicked.connect(self.playaudio)
        self.pushButton_6.clicked.connect(self.pauseplay)
        # 设置信号和槽----产生波形图、频谱图、语图
        self.pushButton_3.clicked.connect(self.plot_waveform)
        self.pushButton_4.clicked.connect(self.plot_spectrogram)
        self.pushButton_7.clicked.connect(self.plot_phonogram)
        # 设置信号和槽----录入信号数据
        self.pushButton_8.clicked.connect(self.logwaveinfo)

    def next(self):
        self.curor += 1
        if self.get_infos and self.curor < len(self.infos):
            self.label_5.setText("当前选中WAV文件为：<Font color='red'>{}</Font>".format(self.infos[self.curor][self.titles[0]]))
        if self.curor >= len(self.infos):
            self.curor = len(self.infos) - 1
        self.getdata()
        self.clear_canvas()

    def last(self):
        self.curor -= 1
        if self.get_infos and 0 <= self.curor < len(self.infos):
            self.label_5.setText("当前选中WAV文件为：<Font color='red'>{}</Font>".format(self.infos[self.curor][self.titles[0]]))
        if self.curor < 0:
            self.curor = 0
        self.getdata()
        self.clear_canvas()

    def playaudio(self):
        wavfile = self.infos[self.curor][self.titles[1]]
        wav_reader = wave.convertbytes2wavereader(wavfile)
        self.wavoprter.pause = False
        play_thread = mythread.MyThread(self.wavoprter.playwav, wav_reader)
        play_thread.start()

    def pauseplay(self):
        self.wavoprter.pause = True

    def initplot_waveform(self):
        pw = pg.PlotWidget()

        pw.showGrid(x=True, y=True)
        pw.setLabel(axis="left", text="Amplitude / V")
        pw.setLabel(axis="bottom", text="t / s")
        pw.setTitle("Wave")

        # 波形图绘制 数据初始化
        self.waveform.update({"curve1": pw.plot(pen='r', name='y1')})
        self.waveform.update({"curve2": pw.plot(pen='g', name='y2')})

        # 主窗口布局
        layout = QVBoxLayout()
        layout.addWidget(pw)  # 将pw加入到布局中
        # 给控件应用布局
        self.widget.setLayout(layout)

    def initplot_spectrogram(self):
        pw = pg.PlotWidget()
        pw.showGrid(x=True, y=True)
        pw.setLabel(axis="left", text="Amp/ dB")
        pw.setLabel(axis="bottom", text="Freq / Hz")
        pw.setTitle("Frequency")

        # 频谱图绘制 数据初始化
        self.spectrogram.update({"curve1": pw.plot(pen='b', name='freq')})

        # 主窗口布局
        layout = QVBoxLayout()
        layout.addWidget(pw)  # 将pw加入到布局中
        # 给控件应用布局
        self.widget_2.setLayout(layout)

    def initplot_phonogram(self):
        figure = plt.figure(facecolor='#FFFFFF')  # 可选参数,facecolor为背景颜色
        canvas = FigureCanvas(figure)
        plt.axis([0, 70, 0, 25000])
        plt.xlabel('Time(s)', fontdict={"color": "black"})
        plt.ylabel('Frequency', fontdict={"color": "black"})
        plt.title("Spectrogram", fontdict={"color": "black"})

        # 语图绘制 数据初始化
        self.phonogram.update({"canvas": canvas})

        # 主窗口布局
        layout = QVBoxLayout()
        layout.addWidget(canvas)
        # 给控件应用布局
        self.widget_3.setLayout(layout)

    def plot_waveform(self):
        fs = 3000
        t0 = np.arange(0, len(self.data[0])) * (1.0 / fs)
        t1 = np.arange(0, len(self.data[1])) * (1.0 / fs)

        try:
            self.waveform["curve1"].setData(t0[:100000], self.data[0][:100000])
            self.waveform["curve2"].setData(t1[:100000], self.data[1][:100000])
        except IndexError:
            self.waveform["curve1"].setData(t0, self.data[0])
            self.waveform["curve2"].setData(t1, self.data[1])

    def plot_spectrogram(self):
        N = 44100
        start = int(len(self.data[0]) / 2)
        # 开始采样位置
        df = self.framerate / (N - 1)
        # 分辨率
        freq = [df * n for n in range(0, N)]
        # N个元素
        wave_data = self.data[0][start:start + N]

        freq_amp = np.fft.fft(wave_data) * 2 / N

        self.spectrogram["curve1"].setData(freq[:round(len(freq) / 2)], abs(freq_amp[:round(len(freq_amp) / 2)]))

    def plot_phonogram(self):
        plt.specgram(self.data[0], Fs=self.framerate, scale_by_freq=True, sides='default')  # 绘制语谱
        self.phonogram["canvas"].draw()

    def clear_canvas(self):
        self.waveform["curve1"].setData([0], [0])
        self.waveform["curve2"].setData([0], [0])
        self.spectrogram["curve1"].setData([0], [0])

        plt.clf()
        plt.axis([0, 7, 0, 50000])
        plt.xlabel('Time(s)', fontdict={"color": "black"})
        plt.ylabel('Frequency', fontdict={"color": "black"})
        plt.title("Spectrogram", fontdict={"color": "black"})
        self.phonogram["canvas"].draw()
        pass

    def logwaveinfo(self):
        self.sqloprter.settable("wavinfotable")
        info = []
        wavname = self.infos[self.curor]["wavname"]
        info.append(wavname)
        for p in self.params:
            info.append(p)
        _, commit_info = self.sqloprter.insert2sql(info)
        if _:
            self.qmessageBox.information(self.MainWindow, "提示", commit_info)
        else:
            self.qmessageBox.warning(self.MainWindow, "提示", commit_info)
        self.sqloprter.settable("wavtable")

    def getdata(self):
        wav_reader = wave.convertbytes2wavereader(self.infos[self.curor][self.titles[1]])
        self.params = wav_reader.getparams()
        self.framerate = wav_reader.getframerate()
        self.data = self.wavoprter.readwav(wav_reader)

    def getinfos(self):
        self.get_infos, self.infos = self.sqloprter.gettableinfos()
        self.titles = self.sqloprter.gettabletitles()

    def setsqloprter(self):
        is_link, link_info = self.sqloprter.link2sql()
        if not is_link:
            print(link_info)
            raise Exception("没能连接上数据库~你说气人不气人。。。")
        else:
            self.sqloprter.settable("wavtable")

    def init_tips(self):
        self.get_infos, self.infos = self.sqloprter.gettableinfos()
        self.titles = self.sqloprter.gettabletitles()
        self.curor = 0
        if self.get_infos:
            self.label_5.setText("当前选中WAV文件为：<Font color='red'>{}</Font>".format(self.infos[0][self.titles[0]]))

    def settableWidget(self):
        try:
            clm_count = len(self.titles)
            row_count = 25
            clm, row = 0, 1
            self.tableWidget.setColumnCount(clm_count)
            # 为表格设置行
            self.tableWidget.setRowCount(row_count)
            # 为表格设置列
            self.tableWidget.verticalHeader().setVisible(False)
            self.tableWidget.horizontalHeader().setVisible(False)
            # 为表格设置表头不可见
            self.tableWidget.resizeColumnsToContents()
            self.tableWidget.resizeRowsToContents()
            # 为表格设置行宽，列宽自适应
            self.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
            # 为表格设置表格头自适应模式
            self.tableWidget.horizontalScrollBar().setStyleSheet("QScrollBar{background:red; height;10px;}")

            self.tableWidget.setRowHeight(0, 30)
            for title in self.titles:
                item = QTableWidgetItem(title)
                item.setTextAlignment(Qt.AlignHCenter)
                self.tableWidget.setItem(0, clm, item)
                clm += 1
            if self.get_infos:
                for row in range(1, len(self.infos)+1):
                    for clm, title in enumerate(self.titles):
                        item = self.infos[row-1][title]
                        if len(item) > 100:
                            item = str(type(item))
                        item1 = QTableWidgetItem(item)
                        item1.setTextAlignment(Qt.AlignCenter)
                        self.tableWidget.setItem(row, clm, item1)
        except Exception as e:
            self.qmessageBox.warning(self.MainWindow, "错误信息", e.args[1])

    def setMainWindow(self):
        self.MainWindow.setWindowFlags(Qt.WindowMinimizeButtonHint)
        self.MainWindow.setFixedSize(self.MainWindow.width(), self.MainWindow.height())

    def setstylesheet(self):
        self.pushButton.setStyleSheet("QPushButton{border-radius:10px;padding:2px 4px;}"
                                      "QPushButton:hover{border:2px solid skyblue;border-radius:8px;padding:2px 4px;}"
                                      "QPushButton:pressed{border:2px solid white;border-radius:8px;padding:2px 4px;"
                                      "background-color:skyblue;}"
                                      )
        self.pushButton_2.setStyleSheet("QPushButton{border-radius:8px;padding:2px 4px;}"
                                        "QPushButton:hover{border:2px solid skyblue;border-radius:8px;padding:2px 4px;}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:8px;padding:2px 4px;"
                                        "background-color:skyblue;}"
                                        )
        self.pushButton_3.setStyleSheet("QPushButton{border:2px groove white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#33CCFF}"
                                        "QPushButton:hover{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD;}"
                                        )
        self.pushButton_4.setStyleSheet("QPushButton{border:2px groove white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#33CCFF}"
                                        "QPushButton:hover{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD;}"
                                        )
        self.pushButton_5.setStyleSheet("QPushButton{border-radius:8px;padding:2px 4px;}"
                                        "QPushButton:hover{border:2px solid skyblue;border-radius:8px;padding:2px 4px;}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:8px;padding:2px 4px;"
                                        "background-color:skyblue;}"
                                        )
        self.pushButton_6.setStyleSheet("QPushButton{border-radius:8px;padding:2px 4px;}"
                                        "QPushButton:hover{border:2px solid skyblue;border-radius:8px;padding:2px 4px;}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:8px;padding:2px 4px;"
                                        "background-color:skyblue;}"
                                        )
        self.pushButton_7.setStyleSheet("QPushButton{border:2px groove white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#33CCFF}"
                                        "QPushButton:hover{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD;}"
                                        )
        self.pushButton_8.setStyleSheet("QPushButton{border:2px groove white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#33CCFF}"
                                        "QPushButton:hover{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD}"
                                        "QPushButton:pressed{border:2px solid white;border-radius:10px;padding:2px 4px;"
                                        "background-color:#FFFACD;}"
                                        )
        # self.tableWidget.setStyleSheet("QTableWidget{border:2px;border-color:black;border-style:groove;font:bold;"
        #                                "border-radius:15px;background:transparent;}")
        self.tableWidget.setStyleSheet("QTableWidget{border:2px;border-color:black;border-style:groove;"
                                       "background:transparent;"
                                       "font:20px;"
                                       "font-family:华文新魏;"
                                       "border-radius:5px;}")
        self.label.setStyleSheet("QLabel{color:black; font-family: 宋体;font-size:32px;border:none;text-align:center;}")
        self.label_2.setStyleSheet("QLabel{color:black; font-family: 宋体;font-size:32px;border:none;text-align:center;}")
        self.label_3.setStyleSheet("QLabel{color:black; font-family: 宋体;font-size:32px;border:none;text-align:center;}")
        self.label_4.setStyleSheet("QLabel{color:black; font-family: 宋体;font-size:32px;border:none;text-align:center;}")
        self.label_5.setStyleSheet("QLabel{color:black; font-family: 宋体;font-size:15px;border:none;text-align:center;}")
        self.widget.setStyleSheet("QWidget{border:8px;border-color:gray;border-style:groove;font:bold;"
                                  "border-radius:15px;background:transparent;}")
        self.widget_2.setStyleSheet("QWidget{border:8px;border-color:gray;border-style:groove;font:bold;"
                                    "border-radius:15px;background:transparent;}")
        self.widget_3.setStyleSheet("QWidget{border:8px;border-color:gray;border-style:groove;font:bold;"
                                    "border-radius:15px;background:transparent;}")
        self.groupBox.setStyleSheet("QGroupBox{border:2px;background-color: #DDDDDD;border-radius:10px}")
        self.groupBox_2.setStyleSheet("QGroupBox{border:2px;background-color: #DDDDDD;border-radius:10px}")
        self.MainWindow.setStyleSheet("QMainWindow{image:url(./image/pic5.jpg);}")



